// ===========================================================================
// Mutex.h : Header / Source file for Mutex
// ---------------------------------------------------------------------------
// Copyright (C) 2011 by Kevin Fisher
// ---------------------------------------------------------------------------
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//-----------------------------------------------------------------------------
// Author: Kevin Fisher <fisher.kevin.g -at- gmail.com> 
// Date:   Sat Aug 13 2011 14:15 EST
// ============================================================================

#ifndef MUTEX_H_
#define MUTEX_H_

// ============================================================================ 

#include <pthread.h>

// ============================================================================ 

/// <summary>
/// A basic mutex class.
/// </summary>
/// <remarks>
/// There are two ways that this class can be used.
/// <list type="bullet">
///    <item>
///    The first is to use it like you would a normal mutex by calling the 
///    lock() method to acquire the lock and unlock() to release the lock.
///    </item>
///   <item>
///   The preferred way is to use the ScopeLock nested-class. This class
///   automatically releases the lock when it goes out of scope. 
///   </item>
/// </list>
/// </remarks>
class Mutex
{
public:
	/// <summary>
	/// Constructor - Initializes the pthread mutex
	/// </summary>
	Mutex(void)
	{
		pthread_mutex_init(&mutex, NULL);
	};

	/// <summary>
	/// Acquires the lock. 
	/// </summary>
	void lock(void)
	{
		pthread_mutex_lock(&mutex);
	};

	/// <summary>
	/// Releases the lock. 
	/// </summary>
	void unlock(void)
	{
		pthread_mutex_unlock(&mutex);
	};
	
	/// <summary>
	/// Acquires the lock upon initialization and releases it when deallocated
	/// </summary>
	class ScopeLock
	{
	public:
		/// <summary>
		/// Acquires the provided lock
		/// </summary>
		/// <param name="p_mutex">The mutex that is being acquired</param>
		ScopeLock(Mutex &p_mutex)
			: m_mutex(p_mutex)
		{
			m_mutex.lock();
		};

		/// <summary>
		/// Releases the lock
		/// </summary>
		~ScopeLock(void)
		{
			m_mutex.unlock();
		};
		
	private:
		Mutex &m_mutex;
	};
	
private:
	pthread_mutex_t mutex;
};




// ============================================================================ 

#endif // MUTEX_H_ //

// ============================================================================ 

// ------------------------------[ END OF CODE ]-------------------------------

/// \file Mutex.h
/// \author Kevin Fisher <fisher.kevin.g -at- gmail.com> 
/// \date \c Created Sat Aug 13 2011 15:10 EST
